﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using Fee;
using Identity;
using Microsoft.AspNetCore.Identity;

namespace JwtWebApi.Data
{
    public class UserInitData
    {
        public string UserName { get; set; }
        public string Name { get; set; }

        public string[] Roles { get; set; }
    }

    public static class SeedData
    {
        public static void Initialize(IServiceProvider serviceProvider)
        {

            if (HasInit())
                return;

            var applicationDbContext =
                serviceProvider.GetService(typeof(ApplicationDbContext)) as ApplicationDbContext;

            InitPermission(serviceProvider, applicationDbContext);
            applicationDbContext.SaveChanges();

            //district
            var Districts = InitDistrict(applicationDbContext);
            applicationDbContext.SaveChanges();

            ProjectSetting(applicationDbContext);
            applicationDbContext.SaveChanges();
            //workProcess
            WorkflowDataSeed.PreDelegateDeisgn(applicationDbContext);
            WorkflowDataSeed.Settlememnt(applicationDbContext);
            WorkflowDataSeed.DelegateOrderDesign(applicationDbContext);
            WorkflowDataSeed.AuthProjectOrderItem(applicationDbContext);
            InitSuccess();
            //}
            //catch (Exception ex)
            //{
            //    throw ex;
            //}
        }

        private static void InitSuccess()
        {
            using (var writer = new StreamWriter("logs/init.config"))
            {
                writer.WriteLine("success init seed data @" + DateTime.Now);
            }
        }

        private static bool HasInit()
        {
            return File.Exists("logs/init.config");
        }


        private static void InitPermission(IServiceProvider serviceProvider, ApplicationDbContext dbContext)
        {
            //系统管理员、工程中心、委托管理员、分公司、设计院
            var admin = new UserInitData
            {
                Name = "管理员",
                UserName = User.Admin,
                Roles = new[] { Role.Admin + "|管理员", "users|用户", "designer|设计院", "delegateAdmin|委托管理员",
                    "constructionCenter|工程中心", "company|分公司", "projectOwner|项目负责人","supervisor|监理","construction|施工" }
            };
            var system = new UserInitData
            {
                UserName = User.System,
                Name = "网调平台",
                Roles = new[] { Role.System + "|系统", "users|用户" }
            };
            AddUser(admin, serviceProvider, dbContext);
            AddUser(system, serviceProvider, dbContext);
        }

        private static void AddUser(UserInitData userData, IServiceProvider serviceProvider,
            ApplicationDbContext dbContexts)
        {
            var roleManager =
                serviceProvider.GetService(typeof(RoleManager<Role>)) as RoleManager<Role>;

            var userManager = serviceProvider.GetService(typeof(UserManager<User>)) as UserManager<User>;
            var user = userManager.Users.FirstOrDefault(_ => _.NormalizedUserName == userData.UserName.ToUpper());
            if (user == null)
            {
                user = new User
                {
                    Name = userData.Name,
                    UserName = userData.UserName,
                    EmailConfirmed = true,
                    Email = userData.UserName + "@admin.com"
                };
                var result = userManager.CreateAsync(user, "Pass!23").Result;
                dbContexts.SaveChanges();
            }

            foreach (var role in userData.Roles)
            {
                var nameAry = role.Split("|");

                var adminRole = roleManager.FindByNameAsync(nameAry[0].ToUpper()).Result;
                if (adminRole == null)
                {
                    var rule = new Role(nameAry[0])
                    {
                        Description = nameAry[1]
                    };
                    var createRoleResult = roleManager.CreateAsync(rule).Result;
                    dbContexts.SaveChanges();
                }


                var addRoleResult = userManager.AddToRoleAsync(user, nameAry[0]).Result;
            }

            dbContexts.SaveChanges();
        }

        private static IList<District> InitDistrict(ApplicationDbContext applicationDbContext)
        {
            var str = new[] { "白云", "天河", "越秀", "西区", "番禺", "增城", "黄埔", "花都", "从化" };
            var district = applicationDbContext.Districts.Where(f => str.Contains(f.Name))
                .ToDictionary(f => f.Name, f => f);
            var districts = new List<District>();
            foreach (var name in str)
                if (!district.ContainsKey(name))
                {
                    var distict = new District
                    {
                        Name = name
                    };
                    districts.Add(distict);
                    applicationDbContext.Add(distict);
                }

            applicationDbContext.SaveChanges();
            return districts;
        }

        private static void ProjectSetting(ApplicationDbContext dbContext)
        {/*
            委托专业 站点类型 项目编码 
管道 集客预覆盖、家客预覆盖 T18032110C30H21 
光缆、设备 家客预覆盖 C18302121C23K51 
光缆、设备 集客预覆盖 C18302121C21K71 */
            var list = new List<Tuple<ConstructionType, StationType, string>>();

            list.Add(new Tuple<ConstructionType, StationType, string>(ConstructionType.Pipeline, StationType.CustomerGroupCoverage, "T18032110C30H21"));
            list.Add(new Tuple<ConstructionType, StationType, string>(ConstructionType.Pipeline, StationType.FamilyCoverage, "T18032110C30H21"));

            list.Add(new Tuple<ConstructionType, StationType, string>(ConstructionType.Cable, StationType.FamilyCoverage, "C18302121C23K51"));
            list.Add(new Tuple<ConstructionType, StationType, string>(ConstructionType.Cable, StationType.CustomerGroupCoverage, "C18302121C21K71"));

            list.Add(new Tuple<ConstructionType, StationType, string>(ConstructionType.Equipment, StationType.FamilyCoverage, "C18302121C23K51"));
            list.Add(new Tuple<ConstructionType, StationType, string>(ConstructionType.Equipment, StationType.CustomerGroupCoverage, "C18302121C21K71"));

            foreach (var item in list)
            {
                var setting = dbContext.Set<ProjectSetting>()
                    .FirstOrDefault(f => f.ConstructionType == item.Item1 && f.StationType == item.Item2 &&
                                         f.ProjectNumber == item.Item3);
                if (setting == null)
                {
                    setting = new ProjectSetting()
                    {
                        ConstructionType = item.Item1,
                        StationType = item.Item2,
                        ProjectNumber = item.Item3
                    };
                    dbContext.Update(setting);
                }

            }
        }
    }
}